﻿#pragma once

#include <QObject>
#include <QLinkedList>
#include <qsemaphore.h>


/*为了读写效率，DatType类型不宜过于复杂，一般数据类型和其包装类可以直接使用，
复杂数据类型应使用指针。
*/
template<class DataType>
class DataQueue : public QObject
{
private:
	int bufferSize = 256;//默认数据缓冲区大小
	QLinkedList<DataType> dataBuffer;//数据缓冲区
	QSemaphore usedBuffer;//如果已使用的资源大于0，则可以读取数据
	QSemaphore freeBuffer;//如果剩余空闲资源大于0，则可以写入数据
public:
	explicit DataQueue()
	{
		freeBuffer.release(bufferSize);
	}
	virtual ~DataQueue()
	{}
public:
	void writeData(DataType data)//写入数据
	{
		freeBuffer.acquire();//若缓冲区可用空间不足，则会阻塞在此处
		dataBuffer.append(data);
		usedBuffer.release();
	}
	DataType readData()
	{
		usedBuffer.acquire();//若缓冲区没有数据，则会阻塞在此处
		DataType temp = dataBuffer.takeFirst();
		freeBuffer.release();
		return temp;
	}
	bool isCanWrite()//若可以写入则返回true，否则返回false
	{
		return freeBuffer.available() > 0 ? true : false;
	}
	bool isCanRead()//若可以读取则返回true，否则返回false
	{
		return usedBuffer.available() > 0 ? true : false;
	}
};
